package org.session.service;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.Future;

import org.session.model.RepositoryType;
import org.session.model.Session;
import org.session.model.SessionEntry;

/**
 * Session service contract to represent bare-minimum session management
 * add/get/delete operations.
 * 
 * Various types of state, differentiated mostly by guaranteed lifetime, are:<br/>
 * 1. Transactional persistent state<br/>
 * 2. Single reader / single writer persistent state (e,g,, user profiles, that
 * almost never see concurrent access)<br/>
 * 3. Expendable persistent state (server-side information that could be
 * sacrificed for the sake of correctness or performance, such as clickstream
 * data and access logs)<br/>
 * 4. Session state (e.g., the result set of a previous search, subject to
 * refinement)<br/>
 * 5. Soft state (state that can be reconstructed at any time based on other
 * data sources)<br/>
 * 6. Volatile state<br/>
 * 
 * Reference - G.Candea, A.Fox. Crash-Only Software
 * 
 * Session-data-lifecycle management has been avoided on purpose in order to
 * keep things simple. Consider plugging into guava Service.
 * 
 * TODO:<br/>
 * 1. Plug into the guava Service
 */
public interface SessionService {
    /**
     * Create a Session which is analogous to a trusted-user login.
     * 
     * @return newly created Session
     */
    Future<Session> createSession(int ttlMillis, boolean idempotence);

    /**
     * End the Session represented by given sessionId. This is analogous to a
     * trusted-user logoff operation.
     * 
     * @return success status of operation
     */
    Future<Boolean> endSession(String sessionId, int ttlMillis,
            boolean idempotence);

    /**
     * Delete the Session represented by given sessionId.
     * 
     * @return success status of operation
     */
    Future<Boolean> deleteSession(String sessionId, int ttlMillis,
            boolean idempotence);

    /**
     * Search the Session represented by given sessionId.
     * 
     * @return previously created Session searched by given sessionId
     */
    Future<Session> searchSession(String sessionId, int ttlMillis,
            boolean idempotence);

    /**
     * Add the given SessionEntry to an already-created Session represented by
     * given sessionId.
     * 
     * @return success status of operation
     */
    Future<Boolean> addEntryToSession(String sessionId, SessionEntry entry,
            int ttlMillis, boolean idempotence);

    /**
     * Replace the given SessionEntry in an already-created Session represented
     * by given sessionId.
     * 
     * @return success status of operation
     */
    Future<Boolean> replaceEntryInSession(String sessionId, SessionEntry entry,
            int ttlMillis, boolean idempotence);

    /**
     * Search the given key's SessionEntry from an already-created Session
     * represented by given sessionId.
     * 
     * @return previously created SessionEntry searched by given sessionId and
     *         key
     */
    Future<SessionEntry> getEntryFromSession(String sessionId, String key,
            int ttlMillis, boolean idempotence);

    /**
     * Search the given keys' SessionEntry's from an already-created Session
     * represented by given sessionId.
     * 
     * @return previously created SessionEntry's searched by given sessionId and
     *         keys
     */
    Future<Map<String, SessionEntry>> getEntriesFromSession(String sessionId,
            Collection<String> keys, int ttlMillis, boolean idempotence);

    /**
     * Delete the given key's SessionEntry from an already-created Session
     * represented by given sessionId.
     * 
     * @return success status of operation
     */
    Future<Boolean> deleteKeyFromSession(String sessionId, String key,
            int ttlMillis, boolean idempotence);

    /**
     * Report the type of repository backing this SessionService.
     * 
     * @return RepositoryType backing this SessionService
     */
    RepositoryType getRepositoryType();

    /**
     * Ping backing state repository to check for liveness.
     * 
     * @return success status of operation
     */
    Future<Boolean> pingRepository();

    /**
     * Shutdown backing state repository.
     * 
     * @return success status of operation
     */
    Future<Boolean> shutdownRepository();

}
